﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using LitJson;

namespace Framework
{
    /// <summary>
    /// Kindeditor插件帮助
    /// </summary>
    public class KindeditorHelper
    {
        private readonly HttpContext _context;
        private readonly string _categoryPath;
        private readonly string _belongsPath;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="categoryPath">分类路径 </param>
        /// <param name="belongsPath">所属路径 </param>
        public KindeditorHelper(HttpContext context, string categoryPath, string belongsPath)
        {
            _context = context;
            _categoryPath = categoryPath;
            _belongsPath = belongsPath;

        }
        /// <summary>
        /// 
        /// </summary>
        public void UploadJson()
        {
            //文件保存目录路径
            string savePath = "~/Upload/Kndeditor/" + _categoryPath + "/" + _belongsPath + "/";
            //文件保存目录URL
            String saveUrl = "/Upload/Kndeditor/" + _categoryPath + "/" + _belongsPath + "/";
            //定义允许上传的文件扩展名
            var extTable = new Hashtable
                               {
                                   {"image", "gif,jpg,jpeg,png,bmp"},
                                   {"flash", "swf,flv"},
                                   {"media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb"},
                                   {"file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2"}
                               };
            //最大文件大小
            const int maxSize = 1000000;
            HttpPostedFile imgFile = _context.Request.Files["imgFile"];
            if (imgFile == null)
            {
                ShowError("请选择文件。");
            }
            String dirPath = _context.Server.MapPath(savePath);
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }
            String dirName = _context.Request.QueryString["dir"];
            if (String.IsNullOrEmpty(dirName))
            {
                dirName = "image";
            }
            if (!extTable.ContainsKey(dirName))
            {
                ShowError("目录名不正确。");
            }
            if (imgFile != null)
            {
                String fileName = imgFile.FileName;
                var extension = Path.GetExtension(fileName);
                if (extension != null)
                {
                    String fileExt = extension.ToLower();

                    if (imgFile.InputStream.Length > maxSize)
                    {
                        ShowError("上传文件大小超过限制。");
                    }

                    if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(((String)extTable[dirName]).Split(','), fileExt.Substring(1).ToLower()) == -1)
                    {
                        ShowError("上传文件扩展名是不允许的扩展名。\n只允许" + ((String)extTable[dirName]) + "格式。");
                    }
                    //创建文件夹
                    dirPath += dirName + "\\";
                    saveUrl += dirName + "/";
                    if (!Directory.Exists(dirPath))
                    {
                        Directory.CreateDirectory(dirPath);
                    }
                    String ymd = DateTime.Now.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo);
                    dirPath += ymd + "\\";
                    saveUrl += ymd + "/";
                    if (!Directory.Exists(dirPath))
                    {
                        Directory.CreateDirectory(dirPath);
                    }

                    String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", DateTimeFormatInfo.InvariantInfo) + fileExt;
                    String filePath = dirPath + newFileName;

                    imgFile.SaveAs(filePath);

                    String fileUrl = saveUrl + newFileName;

                    var hash = new Hashtable();
                    hash["error"] = 0;
                    hash["url"] = fileUrl;
                    _context.Response.AddHeader("Content-Type", "text/html; charset=UTF-8");
                    _context.Response.Write(JsonMapper.ToJson(hash));
                }
            }
            _context.Response.End();
        }

        /// <summary>
        /// 
        /// </summary>
        public void FileManagerJson()
        {
            string rootPath = "~/Upload/Kndeditor/" + _categoryPath + "/" + _belongsPath + "/";
            //根目录URL，可以指定绝对路径，比如 http://www.yoursite.com/attached/
            String rootUrl = "/Upload/Kndeditor/" + _categoryPath + "/" + _belongsPath + "/";
            //图片扩展名
            const string fileTypes = "gif,jpg,jpeg,png,bmp";
            String currentPath;
            String currentUrl;
            String currentDirPath;
            String moveupDirPath;
            String dirPath = _context.Server.MapPath(rootPath);
            String dirName = _context.Request.QueryString["dir"];
            if (!String.IsNullOrEmpty(dirName))
            {
                if (Array.IndexOf("image,flash,media,file".Split(','), dirName) == -1)
                {
                    _context.Response.Write("Invalid Directory name.");
                    _context.Response.End();
                }
                dirPath += dirName + "\\";
                rootUrl += dirName + "/";
                if (!Directory.Exists(dirPath))
                {
                    Directory.CreateDirectory(dirPath);
                }
            }

            //根据path参数，设置各路径和URL
            String path = _context.Request.QueryString["path"];
            path = String.IsNullOrEmpty(path) ? "" : path;
            if (path == "")
            {
                currentPath = dirPath;
                currentUrl = rootUrl;
                currentDirPath = "";
                moveupDirPath = "";
            }
            else
            {
                currentPath = dirPath + path;
                currentUrl = rootUrl + path;
                currentDirPath = path;
                moveupDirPath = Regex.Replace(currentDirPath, @"(.*?)[^\/]+\/$", "$1");
            }

            //排序形式，name or size or type
            String order = _context.Request.QueryString["order"];
            order = String.IsNullOrEmpty(order) ? "" : order.ToLower();

            //不允许使用..移动到上一级目录
            if (Regex.IsMatch(path, @"\.\."))
            {
                _context.Response.Write("Access is not allowed.");
                _context.Response.End();
            }
            //最后一个字符不是/
            if (path != "" && !path.EndsWith("/"))
            {
                _context.Response.Write("Parameter is not valid.");
                _context.Response.End();
            }
            //目录不存在或不是目录
            if (!Directory.Exists(currentPath))
            {
                _context.Response.Write("Directory does not exist.");
                _context.Response.End();
            }

            //遍历目录取得文件信息
            string[] dirList = Directory.GetDirectories(currentPath);
            string[] fileList = Directory.GetFiles(currentPath);

            switch (order)
            {
                case "size":
                    Array.Sort(dirList, new NameSorter());
                    Array.Sort(fileList, new SizeSorter());
                    break;
                case "type":
                    Array.Sort(dirList, new NameSorter());
                    Array.Sort(fileList, new TypeSorter());
                    break;
                default:
                    Array.Sort(dirList, new NameSorter());
                    Array.Sort(fileList, new NameSorter());
                    break;
            }

            var result = new Hashtable();
            result["moveup_dir_path"] = moveupDirPath;
            result["current_dir_path"] = currentDirPath;
            result["current_url"] = currentUrl;
            result["total_count"] = dirList.Length + fileList.Length;
            var dirFileList = new List<Hashtable>();
            result["file_list"] = dirFileList;
            foreach (string t in dirList)
            {
                var dir = new DirectoryInfo(t);
                var hash = new Hashtable();
                hash["is_dir"] = true;
                hash["has_file"] = (dir.GetFileSystemInfos().Length > 0);
                hash["filesize"] = 0;
                hash["is_photo"] = false;
                hash["filetype"] = "";
                hash["filename"] = dir.Name;
                hash["datetime"] = dir.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
                dirFileList.Add(hash);
            }
            foreach (string t in fileList)
            {
                var file = new FileInfo(t);
                var hash = new Hashtable();
                hash["is_dir"] = false;
                hash["has_file"] = false;
                hash["filesize"] = file.Length;
                hash["is_photo"] = (Array.IndexOf(fileTypes.Split(','), file.Extension.Substring(1).ToLower()) >= 0);
                hash["filetype"] = file.Extension.Substring(1);
                hash["filename"] = file.Name;
                hash["datetime"] = file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
                dirFileList.Add(hash);
            }
            _context.Response.AddHeader("Content-Type", "application/json; charset=UTF-8");
            _context.Response.Write(JsonMapper.ToJson(result));
            _context.Response.End();
        }

        private void ShowError(string message)
        {
            var hash = new Hashtable();
            hash["error"] = 1;
            hash["message"] = message;
            _context.Response.AddHeader("Content-Type", "text/html; charset=UTF-8");
            _context.Response.Write(JsonMapper.ToJson(hash));
            _context.Response.End();
        }



        /// <summary>
        /// 
        /// </summary>
        public class NameSorter : IComparer
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public int Compare(object x, object y)
            {
                if (x == null && y == null)
                {
                    return 0;
                }
                if (x == null)
                {
                    return -1;
                }
                if (y == null)
                {
                    return 1;
                }
                var xInfo = new FileInfo(x.ToString());
                var yInfo = new FileInfo(y.ToString());
                return String.CompareOrdinal(xInfo.FullName, yInfo.FullName);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public class SizeSorter : IComparer
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public int Compare(object x, object y)
            {
                if (x == null && y == null)
                {
                    return 0;
                }
                if (x == null)
                {
                    return -1;
                }
                if (y == null)
                {
                    return 1;
                }
                var xInfo = new FileInfo(x.ToString());
                var yInfo = new FileInfo(y.ToString());

                return xInfo.Length.CompareTo(yInfo.Length);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public class TypeSorter : IComparer
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public int Compare(object x, object y)
            {
                if (x == null && y == null)
                {
                    return 0;
                }
                if (x == null)
                {
                    return -1;
                }
                if (y == null)
                {
                    return 1;
                }
                var xInfo = new FileInfo(x.ToString());
                var yInfo = new FileInfo(y.ToString());
                return String.CompareOrdinal(xInfo.Extension, yInfo.Extension);
            }
        }



    }
}